; NAME:
; gauge_reform_flux_AS.pro
;
; PURPOSE:
; Reforms the data to match the required temporal frequency by either averaging from 3hourly to monthly
; or by replicating a monthly flux to 3 hourly frequency.
;
; CATEGORY:
; Regridding
;
; CALLING SEQUENCE:
; gauge_reform_flux, InDate, InTime, InFlux, OutDate, OutTime, OutFlux, Year
;
; INPUTS:
; InDate = In date in string format YYYYMMDD
; InTime = Time in odd MOZART time format
; OutDate = Desired date in string format YYYYMMDD
; OutTime = Desired time in odd MOZART time format
; Year = The year you want to process
; Flux = The flux field that needs to be matched of the format [X,Y,Time]
;
; OUTPUTS:
;
; SIDE EFFECTS:
;
; RESTRICTIONS:
; Assumes that only a single years worth of data is input
;
; PROCEDURE:
;
; MODIFICATION HISTORY:
;   Written Mar 3, 2014 by as13988
PRO gauge_reform_flux, InDate, InTime, InFlux, OutDate, OutTime, OutFlux, Year, DAILY = Daily

  InJD = mr_mozdate(InDate)
  OutJD = mr_mozdate(OutDate)
  
  CalDat, InJD, InMonth, InDay, InYear
  CalDat, OutJD, OutMonth, OutDay, OutYear
  
  ; Need to ensure that the InFlux is in the form lonxlatxtime
  if N_elements(size(InFlux, /DIMENSIONS)) ne 3 then InFlux = reform(InFlux, [size(InFlux, /DIMENSIONS), 1])
  
  
  ; Check that it's just a single year's worth of data
  if max(InYear) - min(InYear) ne 0 then begin
  
    Print, "You've suplied more than one year's worth of data"
    Print, "The given data spans " + strtrim(min(InYear),2) + ' to ' + strtrim(max(InYear),2)
    
  endif
  
  if (n_elements(OutDate) lt n_elements(InDate)) then CaseType = 0
  if (n_elements(OutDate) gt n_elements(InDate)) then CaseType = 1
  if (n_elements(OutDate) eq n_elements(InDate)) then CaseType = 2
  if keyword_set(DAILY) eq 1 then CaseType = 3
  
  Data = !null
  Quiet = 0
  
  ; Go through the three options
  ; 1) Average from higher frequency to monthly
  ; 2) Replicate from lower freqency to higher
  ; 3) Exact same number of points assume that the time frequency matches
  ; 4) Want daily averages
  
  
  Case (CaseType) of
  
    0: begin
    
      print, 'Calculating Monthly frequency from higher frequency data'
      
      for k = 0L, 12-1 do begin ; Month loop
      
        Month_Index = where(InMonth eq k+1, count) ; may be reforming the data for a year that is
        ; different the the actual year of the data
        ; e.g. if we're replicating for missing years
        
        Month_ave = mean(InFlux[*,*,Month_Index],DIMENSION=3)
        
        Data = [[[Data]], [[Month_Ave]]]
        
      endfor ; Month loop
      
    end
    
    
    1: begin
    
      print, 'Replicating 3hourly data from lower freqency data'
      
      For k = 0L, 12-1 do begin ; Month loop
      
        Month_Index = where(InMonth eq k+1, count) ; may be reforming the data for a year that is
        ; different the the actual year of the data
        ; e.g. if we're replicating for missing years
        
        if count gt 0 then Month_Flux = reform(InFlux[*,*,Month_index]) else begin
          Month_Flux = InFlux
          
          print, 'Using flux ' + strtrim(InDate, 2) + ' for ' + Strtrim(Year, 2) + '/' + strtrim(k+1,2)
          
        endelse
        
        ; determine the number of 3hr time blocks in that month
        ;NoBlocks = (Monthdays(Year, k+1))*8
        NoBlocks  = N_Elements(Where(OutMonth eq k+1))
        
        Month_Ave = rebin(Month_Flux, (Size(InFlux, /DIMENSIONS))[0], (Size(InFlux, /DIMENSIONS))[1], NoBlocks)
        
        Data = [[[Data]], [[Month_Ave]]]
        
      endfor ;Month Loop
      
    end
    
    
    2: begin
    
      if Quiet eq 0 then print, 'Same number of points in file as required in the output'
      
      Data = InFlux
      
    end
    
    
    3: begin
    
      print, 'Making daily averages'
      
      if (n_elements(OutDate) lt n_elements(InDate)) then begin
        ; Need to make daily averages from > daily data
        Print, 'Making daily averages from more than daily data'
        
        ; loop through each day using the InTime variable
        ; may be reforming the data for a year that is
        ; different the the actual year of the data
        ; e.g. if we're replicating for missing years
        ; May end up making data for a leap year form an non leap year or vice versa
        
        for j = 0L, 12-1 do begin
        
          ; Extract data for that month
          Month_Index = where(InMonth eq j+1, count)
          
          Month_Data = InFlux[*,*,Month_Index]
          
          NoDays = MONTHDAYS(Outyear[0], j+1)
          
          for i = 0L, NoDays-1 do begin
          
            Day_Index = where(InDay[Month_Index] eq i+1, count)
            
            if (count eq 0) then begin
              Day_Index = where(InDay[Month_Index] eq i, count)
            endif
            
            Day_ave = mean(Month_Data[*,*,Day_Index],DIMENSION=3)
            
            Data = [[[Data]], [[Day_Ave]]]
            
            
          endfor ; End day loop
          
        endfor ; End month loops
        
      endif
      
      
      if (n_elements(OutDate) gt n_elements(InDate)) then begin
        ; Need to make daily averages by replicating < daily data
        Print, 'Making daily averages by replicating data of Monthly frequency'
        
        For k = 0L, 12-1 do begin ; Month loop
        
          Month_Index = where(InMonth eq k+1, count) ; may be reforming the data for a year that is
          ; different the the actual year of the data
          ; e.g. if we're replicating for missing years
          
          if count gt 0 then Month_Flux = reform(InFlux[*,*,Month_index]) else begin
            Month_Flux = InFlux
            
            print, 'Using flux ' + strtrim(InDate, 2) + ' for ' + Strtrim(Year, 2) + '/' + strtrim(k+1,2)
            
          endelse
          
          ; determine the number of 3hr time blocks in that month
          ;NoBlocks = (Monthdays(Year, k+1))*8
          NoBlocks  = N_Elements(Where(OutMonth eq k+1))
          
          Month_Ave = rebin(Month_Flux, (Size(InFlux, /DIMENSIONS))[0], (Size(InFlux, /DIMENSIONS))[1], NoBlocks)
          
          Data = [[[Data]], [[Month_Ave]]]
          
        endfor ;Month Loop
        
      endif
      
    end
    
    
  endcase
  
  
  
  
  
  OutFlux = Data
  
END